package pear.algorithm;

import java.io.File;
import java.nio.ByteBuffer;
import java.util.BitSet;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

/**
 *
 * @author Dingo
 */
@Setter
@Getter
@AllArgsConstructor
public class SplitFile extends SwingWorker<Void, Integer> {

    private JProgressBar splitProgressBar;
    private String pathOfFileToSplit;
    private String segmentsPath;
    private long segmentWeight;//in MB
    private JButton addButton;

    @Override
    protected Void doInBackground() throws Exception {
        //Wyciąganie nazwy pliku: TODO to powinno znaleźć się w innej klasie
        //tworzenie folderu na plik
        segmentsPath += "\\" + new File(pathOfFileToSplit).getName();
        System.out.println(segmentsPath);
        File file = new File(segmentsPath);
        file.mkdir();
        publish(1);
        splitFile();//dzielenie pliku

        return null;
    }

    @Override
    protected void done() {
        splitProgressBar.setValue(100);
        addButton.setEnabled(true);
    }

    @Override
    protected void process(List<Integer> chunks) {
        for (Integer percent : chunks) {
            splitProgressBar.setValue(percent);
        }
    }

    private void splitFile() {
        Algorithm a = new Algorithm();
        segmentWeight *= 1024 * 1024;
        ReadWrite read = new ReadWrite(pathOfFileToSplit);
        read.open();
        long fileLen = read.getLength();//bajty
        int numberOfFiles = numbersOfFile(fileLen);
        int segmentNumber = 0;
        for (long i = 0; i <= fileLen; i += segmentWeight) {
            int len;
            if (i + segmentWeight > fileLen) {
                len = (int) (fileLen - i);
            } else {
                len = (int) segmentWeight;
            }
            byte[] readBytes = new byte[len];
            read.read(i, readBytes);
            //doklejam ile jest bitów, aby wiedział ile czytać :-)
            byte[] newReadBytes = new byte[len + 4];

            byte[] bytes = ByteBuffer.allocate(4).putInt(len).array();
            System.arraycopy(bytes, 0, newReadBytes, 0, 4);
            System.arraycopy(readBytes, 0, newReadBytes, 4, len);
            String sciezka = segmentsPath + "\\" + "part" + segmentNumber + ".png";
            a.writeBitsToImage(new File(sciezka),
                    BitSet.valueOf(newReadBytes));
            segmentNumber++;

            publish(100 * segmentNumber / numberOfFiles);
        }
        read.close();
    }

    private int numbersOfFile(long fileLen) {
        return (int) Math.floor(fileLen / segmentWeight);
    }
}
